//
// Created by Administrator on 2023/5/9.
//
//#define DEBUG_ANDROID

#include "oem_auth.h"
#include "md5.h"
#include "aes.h"

#ifdef DEBUG_ANDROID

#include "../Log.h"

#endif

#include <stdint.h>
#include <string.h>
#include <stdlib.h>


int aes128_encrypt(char *sn,
                   size_t sn_size,
                   char *company,
                   size_t company_size,
                   char *data,
                   size_t data_size,
                   char *out,
                   size_t out_size) {
    char out_key[16];
    get_key(sn, sn_size, company, company_size, out_key);
    printHex("key", out_key, 16);
    //aes encrypt
    char ivec[16] = {0};
    memcpy(ivec, sn, sn_size);
    printHex("ivec", ivec, 16);
    AES_KEY key;
    if (AES_set_encrypt_key(out_key, AES_128, &key) != 0) {
        return ERROR;
    }
    printHex("plain data", data, data_size);
    AES_cbc_encrypt(data, out, data_size, &key, ivec, AES_ENCRYPT);
    printHex("enc data", out, out_size);
    return SUCCESS;
}

int aes128_decrypt(char *sn,
                   size_t sn_size,
                   char *company,
                   size_t company_size,
                   char *data,
                   size_t data_size,
                   char *out) {
    char out_key[16];
    get_key(sn, sn_size, company, company_size, out_key);
    printHex("key", out_key, 16);
    //aes encrypt
    char ivec[16] = {0};
    memcpy(ivec, sn, sn_size);
    printHex("ivec", ivec, 16);
    AES_KEY key;
    if (AES_set_decrypt_key(out_key, AES_128, &key) != 0) {
        return ERROR;
    }
    printHex("enc data", data, data_size);
    AES_cbc_encrypt(data, out, data_size, &key, ivec, AES_DECRYPT);
#ifdef DEBUG_ANDROID
    LOGI("plain data: %s", out);
#endif
    return SUCCESS;
}

void get_key(char *sn,
             size_t sn_size,
             char *company,
             size_t company_size,
             char out_key[16]) {
    //md5, aes key
    char plain_key[sn_size + company_size];
    memcpy(plain_key, sn, sn_size);
    memcpy(&plain_key[sn_size], company, company_size);
    MD5_CTX context;
    MD5Init(&context);
    MD5Update(&context, plain_key, sn_size + company_size);
    MD5Final(&context, out_key);
}

void printHex(char *tag, char *s, int l) {
    char hex_table[] = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };
    char d[l * 2 + 1];
    d[l * 2] = '\0';
    while (l--) {
        *(d + 2 * l + 1) = hex_table[(*(s + l)) & 0x0f];
        *(d + 2 * l) = hex_table[(*(s + l)) >> 4];
    }
#ifdef DEBUG_ANDROID
    LOGI("%s: %s", tag, d);
#endif
}